<template>
  <!-- 模板部分保持不变 -->
  <div class="theater-app">
    <!-- 顶部工具栏 -->
    <header class="app-header">
      <div class="header-left">
        <button class="back-button" @click="goBack">
          <i class="icon-arrow-left"></i>
        </button>
        <div class="theater-meta">
          <h1 class="theater-title">{{ theaterData.title || '剧场体验' }}</h1>
          <span class="scene-subtitle">{{ currentNodeData.title || '加载中...' }}</span>
        </div>
      </div>

      <div class="header-center">
        <div class="progress-indicator">
          <div class="progress-ring">
            <svg width="40" height="40" viewBox="0 0 40 40">
              <circle
                cx="20"
                cy="20"
                r="18"
                fill="none"
                stroke="rgba(59, 130, 246, 0.1)"
                stroke-width="3"
              />
              <circle
                cx="20"
                cy="20"
                r="18"
                fill="none"
                stroke="url(#progressGradient)"
                stroke-width="3"
                stroke-linecap="round"
                :stroke-dasharray="`${sceneProgress * 1.13} 113`"
                stroke-dashoffset="0"
                transform="rotate(-90 20 20)"
              />
              <defs>
                <linearGradient id="progressGradient">
                  <stop offset="0%" stop-color="#3b82f6" />
                  <stop offset="100%" stop-color="#06b6d4" />
                </linearGradient>
              </defs>
            </svg>
            <span class="progress-text">{{ Math.round(sceneProgress) }}%</span>
          </div>
          <span class="progress-label">场景进度</span>
        </div>
      </div>

      <div class="header-right">
        <div class="player-badge">
          <img
            :src="playerCharacter.avatar"
            :alt="playerCharacter.name"
            class="player-avatar-small"
          />
          <div class="player-info-mini">
            <span class="player-name-mini">{{ playerCharacter.name }}</span>
            <span class="player-status-text">正在扮演</span>
          </div>
        </div>
        <button class="menu-toggle" @click="toggleSidebar">
          <i class="icon-menu"></i>
        </button>
      </div>
    </header>

    <!-- 主要内容区 -->
    <div class="app-content">
      <!-- 对话主区域 -->
      <main class="chat-main" :class="{ 'sidebar-open': sidebarOpen }">
        <!-- 场景信息横幅 -->
        <div
          v-if="showSceneContent"
          class="scene-banner"
          :class="{ expanded: isSceneContentExpanded }"
        >
          <div class="scene-banner-header" @click="toggleSceneContent">
            <div class="scene-banner-title">
              <i class="icon-book"></i>
              <span>{{ currentNodeData.title }}</span>
              <span class="scene-location">
                <i class="icon-location"></i>
                {{ theaterData.location || '剧场场景' }}
              </span>
            </div>
            <button class="expand-btn">
              <i :class="isSceneContentExpanded ? 'icon-chevron-up' : 'icon-chevron-down'"></i>
            </button>
          </div>
          <div class="scene-banner-content" v-show="isSceneContentExpanded">
            <div class="scene-description" v-html="currentNodeData.content"></div>
          </div>
        </div>

        <!-- 对话区域 -->
        <div class="chat-container" ref="dialogueContainer">
          <div class="messages-wrapper">
            <!-- 消息列表 -->
            <div
              v-for="message in chatMessages"
              :key="message.id"
              class="message-item"
              :class="{
                'message-player': message.character_id === playerCharacter.id,
                'message-system': message.message_type === 'system',
              }"
            >
              <!-- 系统消息 -->
              <div v-if="message.message_type === 'system'" class="system-message">
                <div class="system-content">
                  <i class="icon-info"></i>
                  <span>{{ message.message }}</span>
                </div>
              </div>

              <!-- 角色消息 -->
              <div v-else class="character-message">
                <div class="message-avatar">
                  <img
                    :src="getCharacterAvatar(message.character_id)"
                    :alt="message.character_name"
                    class="avatar-img"
                  />
                  <div
                    class="avatar-status"
                    :class="getCharacterStatus(message.character_id)"
                  ></div>
                </div>

                <div class="message-content">
                  <div class="message-header">
                    <span class="character-name">{{ message.character_name }}</span>
                    <span class="message-timestamp">{{ formatTime(message.timestamp) }}</span>
                  </div>
                  <div class="message-bubble">
                    <div class="bubble-content">{{ message.message }}</div>
                  </div>
                </div>
              </div>
            </div>

            <!-- 输入指示器 -->
            <div v-if="isProcessingMessage" class="typing-indicator">
              <div class="typing-avatar">
                <div class="typing-dots">
                  <span></span>
                  <span></span>
                  <span></span>
                </div>
              </div>
              <div class="typing-text">AI角色正在思考...</div>
            </div>

            <!-- 空状态 -->
            <div v-if="chatMessages.length === 0 && !isLoading" class="empty-chat">
              <div class="empty-icon">
                <i class="icon-message-circle"></i>
              </div>
              <h3>开始对话</h3>
              <p>
                您正在扮演 <strong>{{ playerCharacter.name }}</strong
                >，准备与其他角色互动吧！
              </p>
            </div>
          </div>
        </div>

        <!-- 输入区域 -->
        <div class="chat-input-area">
          <!-- 快捷回复 -->
          <div
            v-if="showQuickReplies && quickReplySuggestions.length > 0"
            class="quick-suggestions"
          >
            <button
              v-for="suggestion in quickReplySuggestions"
              :key="suggestion"
              class="suggestion-chip"
              @click="insertQuickReply(suggestion)"
            >
              {{ suggestion }}
            </button>
          </div>

          <!-- 输入框区域 -->
          <div class="input-container">
            <div class="input-wrapper">
              <textarea
                v-model="userReply"
                ref="messageInput"
                class="message-input"
                :class="{ 'has-error': inputError }"
                placeholder="输入你的对话内容..."
                rows="1"
                :disabled="isProcessingMessage || !sessionId"
                @keydown.enter.exact.prevent="submitReply"
                @keydown.enter.shift.exact.prevent="insertNewLine"
                @input="adjustTextareaHeight"
                @focus="onInputFocus"
                @blur="onInputBlur"
              ></textarea>

              <div class="input-actions">
                <div class="input-meta">
                  <span class="char-counter" :class="{ 'over-limit': userReply.length > 500 }">
                    {{ userReply.length }}/500
                  </span>
                  <span class="input-hint">Enter 发送 · Shift+Enter 换行</span>
                </div>

                <div class="input-buttons">
                  <button
                    class="quick-action-btn"
                    @click="insertQuickReply('...')"
                    :disabled="isProcessingMessage"
                  >
                    <i class="icon-more"></i>
                  </button>

                  <button
                    class="send-button"
                    @click="submitReply"
                    :disabled="!canSubmit || isProcessingMessage"
                    :class="{ sending: isProcessingMessage }"
                  >
                    <i v-if="isProcessingMessage" class="icon-loader spinning"></i>
                    <i v-else class="icon-send"></i>
                  </button>
                </div>
              </div>
            </div>

            <!-- 错误提示 -->
            <div v-if="inputError" class="input-error">
              <i class="icon-alert-circle"></i>
              <span>{{ inputError }}</span>
            </div>
          </div>

          <!-- 底部工具栏 -->
          <div class="bottom-toolbar">
            <div class="toolbar-left">
              <span class="message-stats">
                <i class="icon-message-square"></i>
                {{ chatMessages.length }} 条对话
              </span>
            </div>

            <div class="toolbar-actions">
              <button class="toolbar-btn" @click="saveProgress" :disabled="!sessionId">
                <i class="icon-save"></i>
                <span>保存</span>
              </button>

              <button class="toolbar-btn" @click="showHistory">
                <i class="icon-history"></i>
                <span>历史</span>
              </button>

              <button class="toolbar-btn" @click="resetScene" :disabled="isProcessingMessage">
                <i class="icon-refresh"></i>
                <span>重置</span>
              </button>
            </div>
          </div>
        </div>
      </main>

      <!-- 侧边栏 -->
      <aside class="app-sidebar" :class="{ open: sidebarOpen }">
        <div class="sidebar-header">
          <h3>场景信息</h3>
          <button class="close-sidebar" @click="toggleSidebar">
            <i class="icon-x"></i>
          </button>
        </div>

        <div class="sidebar-content">
          <!-- 角色列表 -->
          <div class="sidebar-section">
            <div class="section-header">
              <h4>
                <i class="icon-users"></i>
                角色 ({{ allCharacters.length }})
              </h4>
            </div>

            <div class="characters-grid">
              <div
                v-for="character in allCharacters"
                :key="character.id"
                class="character-card"
                :class="{
                  'is-player': character.id === playerCharacter.id,
                  'is-active': recentlySpokeCharacters.includes(character.id),
                }"
              >
                <div class="character-avatar-wrapper">
                  <img :src="character.avatar" :alt="character.name" class="character-avatar" />
                  <div class="character-badge" :class="getCharacterStatus(character.id)">
                    <i :class="getCharacterStatusIcon(character.id)"></i>
                  </div>
                </div>

                <div class="character-info">
                  <div class="character-name">{{ character.name }}</div>
                  <div class="character-description">
                    {{ character.description.substring(0, 60) }}...
                  </div>
                  <div class="character-stats">
                    <span class="stat">
                      <i class="icon-message"></i>
                      {{ getCharacterMessageCount(character.id) }}
                    </span>
                    <span v-if="character.id === playerCharacter.id" class="stat is-player">
                      <i class="icon-user"></i>
                      您
                    </span>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- 场景详情 -->
          <div class="sidebar-section">
            <div class="section-header">
              <h4>
                <i class="icon-info"></i>
                详细信息
              </h4>
            </div>

            <div class="info-cards">
              <div class="info-card">
                <div class="info-label">剧场</div>
                <div class="info-value">{{ theaterData.title || '未知' }}</div>
              </div>

              <div class="info-card">
                <div class="info-label">节点</div>
                <div class="info-value">{{ currentNodeData.title || '未知' }}</div>
              </div>

              <div class="info-card">
                <div class="info-label">扮演角色</div>
                <div class="info-value">{{ playerCharacter.name || '未知' }}</div>
              </div>

              <div class="info-card">
                <div class="info-label">对话进度</div>
                <div class="info-value">{{ Math.round(sceneProgress) }}% 完成</div>
              </div>
            </div>
          </div>

          <!-- 技能信息 -->
          <div v-if="playerSkills.length > 0" class="sidebar-section">
            <div class="section-header">
              <h4>
                <i class="icon-star"></i>
                角色技能 ({{ playerSkills.length }})
              </h4>
            </div>

            <div class="skills-list">
              <div v-for="skill in playerSkills.slice(0, 8)" :key="skill" class="skill-tag">
                <i class="icon-zap"></i>
                <span>{{ skill }}</span>
              </div>
              <div v-if="playerSkills.length > 8" class="skill-more">
                +{{ playerSkills.length - 8 }} 更多
              </div>
            </div>
          </div>

          <!-- 快捷操作 -->
          <div class="sidebar-section">
            <div class="section-header">
              <h4>
                <i class="icon-settings"></i>
                操作
              </h4>
            </div>

            <div class="action-buttons">
              <button class="action-btn primary" @click="saveProgress" :disabled="!sessionId">
                <i class="icon-save"></i>
                <span>保存进度</span>
              </button>

              <button class="action-btn" @click="changeCharacter">
                <i class="icon-user-switch"></i>
                <span>切换角色</span>
              </button>

              <button class="action-btn" @click="openSettings">
                <i class="icon-settings"></i>
                <span>设置</span>
              </button>

              <button class="action-btn danger" @click="exitExperience">
                <i class="icon-log-out"></i>
                <span>退出体验</span>
              </button>
            </div>
          </div>
        </div>
      </aside>
    </div>

    <!-- 遮罩层 -->
    <div v-if="sidebarOpen" class="sidebar-overlay" @click="toggleSidebar"></div>

    <!-- 加载状态 -->
    <div v-if="isLoading" class="loading-screen">
      <div class="loading-content">
        <div class="loading-spinner">
          <div class="spinner-ring"></div>
        </div>
        <h3>{{ loadingText }}</h3>
        <p>正在初始化剧场体验...</p>
      </div>
    </div>

    <!-- 设置弹窗 -->
    <div v-if="showSettingsModal" class="modal-overlay" @click.self="closeSettings">
      <div class="settings-modal">
        <div class="modal-header">
          <h3>场景设置</h3>
          <button class="close-btn" @click="closeSettings">×</button>
        </div>
        <div class="modal-content">
          <div class="setting-group">
            <label>快捷回复建议</label>
            <div class="toggle-switch">
              <input type="checkbox" v-model="enableQuickReplies" id="quick-replies-toggle" />
              <label for="quick-replies-toggle"></label>
            </div>
          </div>
          <div class="setting-group">
            <label>自动滚动到底部</label>
            <div class="toggle-switch">
              <input type="checkbox" v-model="autoScroll" id="auto-scroll-toggle" />
              <label for="auto-scroll-toggle"></label>
            </div>
          </div>
          <div class="setting-group">
            <label>显示场景描述</label>
            <div class="toggle-switch">
              <input type="checkbox" v-model="showSceneContent" id="scene-content-toggle" />
              <label for="scene-content-toggle"></label>
            </div>
          </div>
          <div class="setting-group">
            <label>显示输入提示</label>
            <div class="toggle-switch">
              <input type="checkbox" v-model="showInputTips" id="input-tips-toggle" />
              <label for="input-tips-toggle"></label>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 历史记录弹窗 -->
    <div v-if="showHistoryModal" class="modal-overlay" @click.self="closeHistory">
      <div class="history-modal">
        <div class="modal-header">
          <h3>对话历史记录</h3>
          <button class="close-btn" @click="closeHistory">×</button>
        </div>
        <div class="modal-content">
          <div class="history-stats">
            <div class="stat">
              <span class="stat-label">总对话：</span>
              <span class="stat-value">{{ chatMessages.length }} 条</span>
            </div>
            <div class="stat">
              <span class="stat-label">您的发言：</span>
              <span class="stat-value">{{ playerMessageCount }} 条</span>
            </div>
            <div class="stat">
              <span class="stat-label">开始时间：</span>
              <span class="stat-value">{{ formatSessionTime() }}</span>
            </div>
          </div>
          <div class="history-list">
            <div
              v-for="message in dialogueMessages"
              :key="message.id"
              class="history-message"
              :class="{ 'player-message': message.character_id === playerCharacter.id }"
            >
              <div class="message-header">
                <span class="speaker-name">{{ message.character_name }}</span>
                <span class="message-timestamp">{{ formatTime(message.timestamp) }}</span>
              </div>
              <div class="message-content">{{ message.message }}</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 消息提示 -->
    <div v-if="errorMessage" class="toast toast-error" :class="{ show: errorMessage }">
      <i class="icon-alert-circle"></i>
      <span>{{ errorMessage }}</span>
      <button @click="clearError"><i class="icon-x"></i></button>
    </div>

    <div v-if="successMessage" class="toast toast-success" :class="{ show: successMessage }">
      <i class="icon-check-circle"></i>
      <span>{{ successMessage }}</span>
      <button @click="clearSuccess"><i class="icon-x"></i></button>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed, nextTick, watch, onBeforeUnmount } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import axios from 'axios'

const router = useRouter()
const route = useRoute()

// 🔧 API客户端配置
const theaterDetailApiClient = axios.create({
  baseURL: 'http://localhost:8803',
  timeout: 30000,
})

const chatApiClient = axios.create({
  baseURL: 'http://127.0.0.1:8801',
  timeout: 30000,
})

// 类型定义
interface Character {
  id: string
  name: string
  description: string
  avatar: string
  selectedSkills?: string[]
}

interface ChatMessage {
  id: string
  character_id: string
  character_name: string
  message: string
  timestamp: string
  message_type: string
}

interface TheaterData {
  title: string
  description: string
  era: string
  location: string
  author: string
}

interface NodeData {
  id: string
  title: string
  content: string
  characterSettings: any
}

interface TheaterDetailData {
  theater_info: TheaterData
  script_nodes: NodeData[]
  characters: Character[]
  available_skills: string[]
}

// 响应式数据
const isLoading = ref(true)
const loadingText = ref('正在加载剧场体验...')
const isProcessingMessage = ref(false)
const userReply = ref('')
const inputError = ref('')
const errorMessage = ref('')
const successMessage = ref('')
const sceneProgress = ref(10)

// UI状态
const showQuickReplies = ref(false)
const showSettingsModal = ref(false)
const showHistoryModal = ref(false)
const isInputFocused = ref(false)
const isSceneContentExpanded = ref(false)
const sidebarOpen = ref(false)

// 设置选项
const enableQuickReplies = ref(true)
const autoScroll = ref(true)
const showSceneContent = ref(true)
const showInputTips = ref(true)

// 会话相关
const sessionId = ref<string>('')
const taskId = ref<string>('')
const selectedCharacterId = ref<string>('')
const selectedNodeId = ref<string>('')
const chatMessages = ref<ChatMessage[]>([])
const sessionStartTime = ref<string>('')

// 剧场数据
const theaterData = reactive<TheaterData>({
  title: '',
  description: '',
  era: '',
  location: '',
  author: '',
})

const currentNodeData = reactive<NodeData>({
  id: '',
  title: '',
  content: '',
  characterSettings: {},
})

const playerCharacter = reactive<Character>({
  id: '',
  name: '',
  description: '',
  avatar: '',
  selectedSkills: [],
})

const allCharacters = ref<Character[]>([])
const recentlySpokeCharacters = ref<string[]>([])
const availableSkills = ref<string[]>([])

// DOM引用
const dialogueContainer = ref<HTMLElement | null>(null)
const messageInput = ref<HTMLTextAreaElement | null>(null)

// 快捷回复建议
const quickReplySuggestions = computed(() => {
  if (!enableQuickReplies.value) return []

  const suggestions = [
    '我明白了',
    '请继续',
    '有什么我可以帮助的吗？',
    '这很有趣',
    '让我想想...',
    '我同意你的看法',
  ]

  return suggestions.slice(0, 4)
})

// 计算属性
const canSubmit = computed(() => {
  return (
    userReply.value.trim().length > 0 &&
    userReply.value.length <= 500 &&
    !isProcessingMessage.value &&
    sessionId.value !== ''
  )
})

const playerMessageCount = computed(() => {
  return chatMessages.value.filter(
    (msg) => msg.character_id === playerCharacter.id && msg.message_type === 'dialogue',
  ).length
})

const playerSkills = computed(() => {
  const normalizeSkillsData = (rawSkills: any): string[] => {
    if (!rawSkills) return []

    if (Array.isArray(rawSkills)) {
      return rawSkills.filter((skill) => typeof skill === 'string' && skill.trim().length > 0)
    }

    if (typeof rawSkills === 'string') {
      try {
        const parsed = JSON.parse(rawSkills)
        return normalizeSkillsData(parsed)
      } catch {
        return rawSkills.trim() ? [rawSkills.trim()] : []
      }
    }

    if (typeof rawSkills === 'object') {
      if (rawSkills.skills && Array.isArray(rawSkills.skills)) {
        return rawSkills.skills.filter(
          (skill: any) => typeof skill === 'string' && skill.trim().length > 0,
        )
      }
      if (rawSkills.name && typeof rawSkills.name === 'string') {
        return [rawSkills.name.trim()]
      }
    }

    return []
  }

  return normalizeSkillsData(playerCharacter.selectedSkills)
})

const dialogueMessages = computed(() => {
  return chatMessages.value.filter((msg) => msg.message_type === 'dialogue')
})

// 监听器
watch(
  chatMessages,
  () => {
    if (autoScroll.value) {
      nextTick(() => {
        scrollToBottom()
      })
    }
  },
  { deep: true },
)

watch(isInputFocused, (focused) => {
  showQuickReplies.value = focused && enableQuickReplies.value
})

// 🔧 核心修改：从API加载剧场数据
const loadTheaterDataFromAPI = async () => {
  try {
    console.log('🎭 开始从API加载剧场数据')

    // 1. 从路由参数获取必要信息
    taskId.value = route.query.task_id as string
    selectedCharacterId.value = route.query.character_id as string
    selectedNodeId.value = route.query.node_id as string

    if (!taskId.value) {
      throw new Error('缺少必要的task_id参数')
    }

    if (!selectedCharacterId.value) {
      throw new Error('缺少必要的character_id参数')
    }

    if (!selectedNodeId.value) {
      throw new Error('缺少必要的node_id参数')
    }

    console.log('📋 路由参数:', {
      taskId: taskId.value,
      characterId: selectedCharacterId.value,
      nodeId: selectedNodeId.value
    })

    // 2. 调用theater_detail API获取剧场数据
    loadingText.value = '正在获取剧场详情...'

    const response = await theaterDetailApiClient.get(`/theater/${taskId.value}`)

    if (!response.data.success) {
      throw new Error(response.data.message || '获取剧场数据失败')
    }

    const theaterDetailData: TheaterDetailData = response.data.data.data
    console.log('✅ 获取到剧场数据:', theaterDetailData)

    // 3. 更新剧场基本信息
    if (theaterDetailData.theater_info) {
      Object.assign(theaterData, theaterDetailData.theater_info)
      console.log('✅ 剧场信息更新完成')
    }

    // 4. 设置所有角色
    if (theaterDetailData.characters && Array.isArray(theaterDetailData.characters)) {
      allCharacters.value = theaterDetailData.characters
      console.log(`✅ 加载 ${allCharacters.value.length} 个角色`)

      // 5. 设置玩家角色
      const playerChar = allCharacters.value.find(char => char.id === selectedCharacterId.value)
      if (playerChar) {
        Object.assign(playerCharacter, playerChar)
        console.log('✅ 玩家角色设置完成:', playerCharacter.name)
      } else {
        throw new Error(`未找到指定的角色: ${selectedCharacterId.value}`)
      }
    }

    // 6. 设置当前节点
    if (theaterDetailData.script_nodes && Array.isArray(theaterDetailData.script_nodes)) {
      const currentNode = theaterDetailData.script_nodes.find(node => node.id === selectedNodeId.value)
      if (currentNode) {
        Object.assign(currentNodeData, currentNode)
        console.log('✅ 当前节点设置完成:', currentNodeData.title)
      } else {
        throw new Error(`未找到指定的节点: ${selectedNodeId.value}`)
      }
    }

    // 7. 设置可用技能
    if (theaterDetailData.available_skills && Array.isArray(theaterDetailData.available_skills)) {
      availableSkills.value = theaterDetailData.available_skills
      console.log(`✅ 加载 ${availableSkills.value.length} 个技能`)
    }

    console.log('🎉 剧场数据加载完成')

  } catch (error) {
    console.error('❌ 加载剧场数据失败:', error)
    showError(error instanceof Error ? error.message : '加载剧场数据失败')
    throw error
  }
}

// 生命周期和方法
onMounted(async () => {
  console.log('🎭 剧场体验页面开始加载')

  try {
    // 🔧 修改：完全从API加载数据
    await loadTheaterDataFromAPI()

    // 初始化聊天会话
    await initializeChatSession()

    // 加载完成
    isLoading.value = false

    console.log('🎉 剧场体验页面加载完成')
  } catch (error) {
    console.error('❌ 页面加载失败:', error)
    showError('页面加载失败，请重试')
    isLoading.value = false
  }
})

onBeforeUnmount(() => {
  clearError()
  clearSuccess()
})

const isAxiosError = (
  error: unknown,
): error is { code?: string; message?: string; response?: any } => {
  return error !== null && typeof error === 'object' && 'code' in error
}

// 会话初始化
const initializeChatSession = async () => {
  try {
    loadingText.value = '正在检查聊天服务连接...'

    // 首先检查服务健康状态
    try {
      const healthResponse = await chatApiClient.get('/health')
      if (!healthResponse.data.success) {
        throw new Error('聊天服务未就绪')
      }
    } catch (healthError) {
      console.error('❌ 聊天服务连接失败:', healthError)
      showError('无法连接到聊天服务，请确保后端服务已启动')
      throw new Error('聊天服务连接失败')
    }

    loadingText.value = '正在初始化对话会话...'

    const response = await chatApiClient.post('/chat/start', {
      theater_title: theaterData.title,
      node_id: currentNodeData.id,
      node_title: currentNodeData.title,
      node_content: currentNodeData.content,
      player_character_id: playerCharacter.id,
      all_characters: allCharacters.value,
      character_settings: currentNodeData.characterSettings,
    })

    if (response.data.success) {
      sessionId.value = response.data.data.session_id
      chatMessages.value = response.data.data.initial_messages || []
      sessionStartTime.value = new Date().toISOString()

      console.log('✅ 聊天会话初始化成功:', sessionId.value)
      showSuccess('会话初始化成功，可以开始对话了！')

      nextTick(() => {
        scrollToBottom()
      })
    } else {
      throw new Error(response.data.message || '初始化会话失败')
    }
  } catch (error) {
    console.error('❌ 初始化聊天会话失败:', error)

    // 🔧 修复：使用类型守卫函数安全处理错误
    if (isAxiosError(error)) {
      if (error.code === 'ERR_NETWORK') {
        showError('网络连接失败，请检查聊天服务是否启动')
      } else if (error.code === 'ECONNREFUSED') {
        showError('无法连接到聊天服务，请启动chat_api.py')
      } else {
        showError('初始化聊天失败，请检查网络连接')
      }
    } else if (error instanceof Error) {
      showError(`初始化失败: ${error.message}`)
    } else {
      showError('初始化聊天失败，请检查网络连接')
    }

    throw error
  }
}

// 消息发送
const submitReply = async () => {
  if (!canSubmit.value) {
    if (userReply.value.trim().length === 0) {
      inputError.value = '请输入回复内容'
    } else if (userReply.value.length > 500) {
      inputError.value = '回复内容不能超过500个字符'
    } else if (!sessionId.value) {
      inputError.value = '会话未初始化，请刷新页面'
    }
    return
  }

  const message = userReply.value.trim()
  userReply.value = ''
  isProcessingMessage.value = true
  clearError()

  // 重置输入框高度
  if (messageInput.value) {
    messageInput.value.style.height = 'auto'
  }

  try {
    const response = await chatApiClient.post('/chat/message', {
      session_id: sessionId.value,
      message: message,
    })

    if (response.data.success) {
      const newMessages = response.data.data.new_messages || []
      chatMessages.value.push(...newMessages)

      updateRecentlySpokeCharacters(newMessages)
      sceneProgress.value = Math.min(100, sceneProgress.value + 5)

      console.log('✅ 消息发送成功，收到', newMessages.length, '条回复')
    } else {
      throw new Error(response.data.message || '发送消息失败')
    }
  } catch (error) {
    console.error('❌ 发送消息失败:', error)
    showError('发送失败，请重试')
    userReply.value = message
  } finally {
    isProcessingMessage.value = false
  }
}

// 更新最近说话的角色
const updateRecentlySpokeCharacters = (newMessages: ChatMessage[]) => {
  const speakers = newMessages
    .filter((msg) => msg.message_type === 'dialogue' && msg.character_id !== playerCharacter.id)
    .map((msg) => msg.character_id)

  recentlySpokeCharacters.value = [
    ...new Set([...speakers, ...recentlySpokeCharacters.value]),
  ].slice(0, 3)
}

// 工具方法
const getCharacterAvatar = (characterId: string) => {
  if (characterId === 'system') {
    return 'https://ui-avatars.com/api/?name=系统&background=6b7280&color=fff'
  }

  const character = allCharacters.value.find((c) => c.id === characterId)
  return character?.avatar || 'https://ui-avatars.com/api/?name=Unknown&background=ef4444&color=fff'
}

const getCharacterStatus = (characterId: string) => {
  if (characterId === playerCharacter.id) return 'player'
  if (recentlySpokeCharacters.value.includes(characterId)) return 'active'
  return 'idle'
}

const getCharacterStatusIcon = (characterId: string) => {
  const status = getCharacterStatus(characterId)
  const icons = {
    player: 'icon-user',
    active: 'icon-message',
    idle: 'icon-sleep',
  }
  return icons[status] || icons.idle
}

const getCharacterMessageCount = (characterId: string) => {
  return chatMessages.value.filter(
    (msg) => msg.character_id === characterId && msg.message_type === 'dialogue',
  ).length
}

const formatTime = (timestamp: string) => {
  const date = new Date(timestamp)
  return date.toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit',
  })
}

const formatSessionTime = () => {
  if (!sessionStartTime.value) return '未知'
  const date = new Date(sessionStartTime.value)
  return date.toLocaleString('zh-CN')
}

const scrollToBottom = () => {
  if (dialogueContainer.value) {
    dialogueContainer.value.scrollTop = dialogueContainer.value.scrollHeight
  }
}

// 输入处理
const clearInputError = () => {
  inputError.value = ''
}

const onInputFocus = () => {
  isInputFocused.value = true
}

const onInputBlur = () => {
  setTimeout(() => {
    isInputFocused.value = false
  }, 200)
}

const insertQuickReply = (text: string) => {
  if (userReply.value) {
    userReply.value += ' ' + text
  } else {
    userReply.value = text
  }

  if (messageInput.value) {
    messageInput.value.focus()
    messageInput.value.setSelectionRange(userReply.value.length, userReply.value.length)
  }

  nextTick(() => {
    adjustTextareaHeight()
  })
}

const insertNewLine = () => {
  userReply.value += '\n'
  nextTick(() => {
    adjustTextareaHeight()
  })
}

const adjustTextareaHeight = () => {
  const textarea = messageInput.value
  if (textarea) {
    textarea.style.height = 'auto'
    textarea.style.height = Math.min(textarea.scrollHeight, 120) + 'px'
  }
}

const toggleSceneContent = () => {
  isSceneContentExpanded.value = !isSceneContentExpanded.value
}

const toggleSidebar = () => {
  sidebarOpen.value = !sidebarOpen.value
}

// 🔧 修改：移除localStorage的保存逻辑
const saveProgress = async () => {
  try {
    // 不再保存到localStorage，只显示提示信息
    showSuccess('进度已自动保存到服务器')
    console.log('✅ 进度保存提示完成（数据已实时同步到服务器）')
  } catch (error) {
    console.error('保存进度提示失败:', error)
    showError('保存进度失败')
  }
}

const showHistory = () => {
  showHistoryModal.value = true
}

const closeHistory = () => {
  showHistoryModal.value = false
}

const resetScene = async () => {
  if (!confirm('确定要重置当前场景吗？这将清除所有对话记录。')) {
    return
  }

  try {
    chatMessages.value = []
    recentlySpokeCharacters.value = []
    sceneProgress.value = 10
    sessionId.value = ''

    await initializeChatSession()
    showSuccess('场景已重置')
  } catch (error) {
    console.error('重置场景失败:', error)
    showError('重置场景失败')
  }
}

const changeCharacter = () => {
  if (confirm('确定要切换角色吗？当前进度已自动保存到服务器。')) {
    router.push('/TheaterList')
  }
}

const exitExperience = () => {
  if (confirm('确定要退出剧场体验吗？当前进度已自动保存到服务器。')) {
    router.push('/TheaterList')
  }
}

// UI控制方法
const goBack = () => {
  if (chatMessages.value.length > 1) {
    if (confirm('确定要离开吗？当前进度已自动保存到服务器。')) {
      router.push('/TheaterList')
    }
  } else {
    router.push('/TheaterList')
  }
}

const openSettings = () => {
  showSettingsModal.value = true
}

const closeSettings = () => {
  showSettingsModal.value = false
}

// 消息提示
const showError = (message: string) => {
  errorMessage.value = message
  setTimeout(() => {
    errorMessage.value = ''
  }, 5000)
}

const showSuccess = (message: string) => {
  successMessage.value = message
  setTimeout(() => {
    successMessage.value = ''
  }, 3000)
}

const clearError = () => {
  errorMessage.value = ''
}

const clearSuccess = () => {
  successMessage.value = ''
}
</script>

<!-- 样式部分保持不变 -->

<style scoped>
.theater-app {
  height: 100vh;
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
  display: flex;
  flex-direction: column;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  overflow: hidden;
}

/* 🎯 顶部工具栏 */
.app-header {
  height: 70px;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(20px);
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px;
  position: relative;
  z-index: 100;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.header-left {
  display: flex;
  align-items: center;
  gap: 16px;
  flex: 1;
  min-width: 0;
}

.back-button {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  border: none;
  background: rgba(59, 130, 246, 0.1);
  color: #3b82f6;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 18px;
}

.back-button:hover {
  background: rgba(59, 130, 246, 0.15);
  transform: translateY(-1px);
}

.theater-meta {
  min-width: 0;
}

.theater-title {
  font-size: 18px;
  font-weight: 700;
  color: #1f2937;
  margin: 0;
  line-height: 1.2;
  background: linear-gradient(135deg, #3b82f6, #06b6d4);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.scene-subtitle {
  font-size: 13px;
  color: #6b7280;
  font-weight: 500;
}

.header-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.progress-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.progress-ring {
  position: relative;
  width: 40px;
  height: 40px;
}

.progress-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 10px;
  font-weight: 600;
  color: #3b82f6;
}

.progress-label {
  font-size: 11px;
  color: #6b7280;
  font-weight: 500;
}

.header-right {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  justify-content: flex-end;
}

.player-badge {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.08), rgba(6, 182, 212, 0.08));
  border-radius: 12px;
  border: 1px solid rgba(59, 130, 246, 0.15);
}

.player-avatar-small {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 2px solid #3b82f6;
  object-fit: cover;
}

.player-info-mini {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.player-name-mini {
  font-size: 13px;
  font-weight: 600;
  color: #1f2937;
  line-height: 1;
}

.player-status-text {
  font-size: 11px;
  color: #6b7280;
}

.menu-toggle {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  border: none;
  background: rgba(107, 114, 128, 0.1);
  color: #6b7280;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 18px;
}

.menu-toggle:hover {
  background: rgba(107, 114, 128, 0.15);
  color: #374151;
}

/* 🏗️ 主内容区 */
.app-content {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.chat-main {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: white;
  transition: margin-right 0.3s ease;
  overflow: hidden;
}

.chat-main.sidebar-open {
  margin-right: 400px;
}

/* 📖 场景横幅 */
.scene-banner {
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.04), rgba(6, 182, 212, 0.04));
  border-bottom: 1px solid rgba(59, 130, 246, 0.08);
  transition: all 0.3s ease;
}

.scene-banner-header {
  padding: 16px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  user-select: none;
}

.scene-banner-title {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  font-weight: 600;
  color: #1f2937;
}

.scene-location {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #6b7280;
  font-weight: 500;
}

.expand-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: none;
  background: rgba(59, 130, 246, 0.1);
  color: #3b82f6;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
}

.scene-banner-content {
  padding: 0 24px 16px;
  border-top: 1px solid rgba(59, 130, 246, 0.08);
  background: rgba(255, 255, 255, 0.5);
}

.scene-description {
  font-size: 14px;
  line-height: 1.6;
  color: #4b5563;
  margin-top: 12px;
}

/* 💬 对话容器 */
.chat-container {
  flex: 1;
  overflow-y: auto;
  scroll-behavior: smooth;
}

.messages-wrapper {
  padding: 24px;
  max-width: 1000px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.message-item {
  display: flex;
  opacity: 0;
  animation: messageSlideUp 0.4s ease-out forwards;
}

@keyframes messageSlideUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-player {
  flex-direction: row-reverse;
}

/* 系统消息 */
.system-message {
  align-self: center;
  max-width: 80%;
}

.system-content {
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.08), rgba(6, 182, 212, 0.08));
  color: #4b5563;
  padding: 12px 16px;
  border-radius: 20px;
  border: 1px solid rgba(59, 130, 246, 0.1);
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
  backdrop-filter: blur(10px);
}

/* 角色消息 */
.character-message {
  display: flex;
  gap: 12px;
  max-width: 75%;
}

.message-player .character-message {
  flex-direction: row-reverse;
}

.message-avatar {
  position: relative;
  flex-shrink: 0;
}

.avatar-img {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  object-fit: cover;
  border: 2px solid rgba(255, 255, 255, 0.8);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.avatar-status {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid white;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.avatar-status.player {
  background: #3b82f6;
}
.avatar-status.active {
  background: #10b981;
}
.avatar-status.idle {
  background: #94a3b8;
}

.message-content {
  flex: 1;
  min-width: 0;
}

.message-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.message-player .message-header {
  justify-content: flex-end;
}

.character-name {
  font-size: 13px;
  font-weight: 600;
  color: #374151;
}

.message-timestamp {
  font-size: 11px;
  color: #9ca3af;
}

.message-bubble {
  position: relative;
}

.bubble-content {
  background: #f9fafb;
  border: 1px solid rgba(0, 0, 0, 0.06);
  border-radius: 18px;
  padding: 14px 18px;
  font-size: 15px;
  line-height: 1.5;
  color: #1f2937;
  word-wrap: break-word;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.message-player .bubble-content {
  background: linear-gradient(135deg, #3b82f6, #2563eb);
  color: white;
  border-color: transparent;
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.25);
}

/* 输入指示器 */
.typing-indicator {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 200px;
}

.typing-avatar {
  width: 44px;
  height: 44px;
  border-radius: 14px;
  background: #f3f4f6;
  display: flex;
  align-items: center;
  justify-content: center;
}

.typing-dots {
  display: flex;
  gap: 3px;
}

.typing-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #6b7280;
  animation: typing 1.4s infinite ease-in-out;
}

.typing-dots span:nth-child(1) {
  animation-delay: 0s;
}
.typing-dots span:nth-child(2) {
  animation-delay: 0.2s;
}
.typing-dots span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0%,
  80%,
  100% {
    opacity: 0.3;
    transform: scale(0.8);
  }
  40% {
    opacity: 1;
    transform: scale(1);
  }
}

.typing-text {
  font-size: 13px;
  color: #6b7280;
  font-style: italic;
}

/* 空状态 */
.empty-chat {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 60px 20px;
  color: #6b7280;
  min-height: 300px;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.5;
}

.empty-chat h3 {
  font-size: 20px;
  font-weight: 600;
  color: #374151;
  margin: 0 0 8px 0;
}

.empty-chat p {
  font-size: 14px;
  margin: 0;
  max-width: 300px;
}

/* 📝 输入区域 */
.chat-input-area {
  background: white;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
  padding: 16px 24px;
}

.quick-suggestions {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.suggestion-chip {
  background: rgba(59, 130, 246, 0.08);
  border: 1px solid rgba(59, 130, 246, 0.15);
  color: #3b82f6;
  padding: 8px 14px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  white-space: nowrap;
  flex-shrink: 0;
}

.suggestion-chip:hover {
  background: rgba(59, 130, 246, 0.12);
  transform: translateY(-1px);
}

.input-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.input-wrapper {
  background: #f9fafb;
  border: 2px solid rgba(0, 0, 0, 0.06);
  border-radius: 24px;
  padding: 12px 16px;
  transition: all 0.2s ease;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.input-wrapper:focus-within {
  border-color: #3b82f6;
  background: white;
  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.08);
}

.message-input {
  border: none;
  background: none;
  font-size: 15px;
  line-height: 1.5;
  color: #1f2937;
  resize: none;
  outline: none;
  font-family: inherit;
  min-height: 24px;
  max-height: 120px;
  overflow-y: auto;
}

.message-input::placeholder {
  color: #9ca3af;
}

.message-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.input-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.input-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: #6b7280;
}

.char-counter.over-limit {
  color: #ef4444;
  font-weight: 600;
}

.input-hint {
  color: #9ca3af;
}

.input-buttons {
  display: flex;
  gap: 8px;
  align-items: center;
}

.quick-action-btn {
  width: 36px;
  height: 36px;
  border-radius: 12px;
  border: none;
  background: rgba(107, 114, 128, 0.08);
  color: #6b7280;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 16px;
}

.quick-action-btn:hover:not(:disabled) {
  background: rgba(107, 114, 128, 0.15);
  color: #374151;
}

.send-button {
  width: 36px;
  height: 36px;
  border-radius: 12px;
  border: none;
  background: linear-gradient(135deg, #3b82f6, #2563eb);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
  font-size: 16px;
  box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
}

.send-button:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

.send-button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.send-button.sending {
  pointer-events: none;
}

.spinning {
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.input-error {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #ef4444;
  font-size: 13px;
  padding: 8px 16px;
  background: rgba(239, 68, 68, 0.05);
  border-radius: 12px;
  border: 1px solid rgba(239, 68, 68, 0.1);
}

/* 🔧 底部工具栏 */
.bottom-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.toolbar-left {
  display: flex;
  align-items: center;
}

.message-stats {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: #6b7280;
}

.toolbar-actions {
  display: flex;
  gap: 12px;
}

.toolbar-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-radius: 12px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  background: white;
  color: #6b7280;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
}

.toolbar-btn:hover:not(:disabled) {
  border-color: #3b82f6;
  color: #3b82f6;
  background: rgba(59, 130, 246, 0.04);
}

.toolbar-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 🎛️ 侧边栏 */
.app-sidebar {
  position: fixed;
  top: 70px;
  right: 0;
  width: 400px;
  height: calc(100vh - 70px);
  background: white;
  border-left: 1px solid rgba(0, 0, 0, 0.06);
  transform: translateX(100%);
  transition: transform 0.3s ease;
  z-index: 50;
  overflow-y: auto;
}

.app-sidebar.open {
  transform: translateX(0);
  box-shadow: -4px 0 20px rgba(0, 0, 0, 0.1);
}

.sidebar-header {
  padding: 20px 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #f9fafb;
}

.sidebar-header h3 {
  font-size: 16px;
  font-weight: 700;
  color: #1f2937;
  margin: 0;
}

.close-sidebar {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: none;
  background: rgba(107, 114, 128, 0.1);
  color: #6b7280;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s ease;
}

.close-sidebar:hover {
  background: rgba(107, 114, 128, 0.15);
}

.sidebar-content {
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.sidebar-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.section-header h4 {
  font-size: 14px;
  font-weight: 600;
  color: #374151;
  margin: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* 角色网格 */
.characters-grid {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.character-card {
  display: flex;
  gap: 12px;
  padding: 16px;
  background: #f9fafb;
  border-radius: 16px;
  border: 2px solid transparent;
  transition: all 0.2s ease;
}

.character-card.is-player {
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.08), rgba(6, 182, 212, 0.08));
  border-color: rgba(59, 130, 246, 0.2);
}

.character-card.is-active {
  background: linear-gradient(135deg, rgba(16, 185, 129, 0.06), rgba(5, 150, 105, 0.06));
  border-color: rgba(16, 185, 129, 0.2);
}

.character-avatar-wrapper {
  position: relative;
  flex-shrink: 0;
}

.character-avatar {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  object-fit: cover;
  border: 2px solid rgba(0, 0, 0, 0.06);
}

.character-badge {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  color: white;
}

.character-badge.player {
  background: #3b82f6;
}
.character-badge.active {
  background: #10b981;
}
.character-badge.idle {
  background: #94a3b8;
}

.character-info {
  flex: 1;
  min-width: 0;
}

.character-name {
  font-size: 14px;
  font-weight: 600;
  color: #1f2937;
  margin-bottom: 4px;
  line-height: 1.2;
}

.character-description {
  font-size: 12px;
  color: #6b7280;
  line-height: 1.4;
  margin-bottom: 8px;
}

.character-stats {
  display: flex;
  gap: 12px;
  align-items: center;
}

.stat {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: #9ca3af;
  font-weight: 500;
}

.stat.is-player {
  background: rgba(59, 130, 246, 0.1);
  color: #3b82f6;
  padding: 2px 6px;
  border-radius: 6px;
  font-weight: 600;
}

/* 信息卡片 */
.info-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.info-card {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #f9fafb;
  border-radius: 12px;
  border: 1px solid rgba(0, 0, 0, 0.04);
}

.info-label {
  font-size: 12px;
  color: #6b7280;
  font-weight: 500;
}

.info-value {
  font-size: 13px;
  color: #1f2937;
  font-weight: 600;
  text-align: right;
}

/* 技能标签 */
.skills-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.skill-tag {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  background: rgba(59, 130, 246, 0.08);
  color: #3b82f6;
  border-radius: 8px;
  font-size: 11px;
  font-weight: 500;
  border: 1px solid rgba(59, 130, 246, 0.15);
}

.skill-more {
  padding: 6px 10px;
  background: #f3f4f6;
  color: #6b7280;
  border-radius: 8px;
  font-size: 11px;
  font-weight: 500;
  border: 1px dashed #d1d5db;
}

/* 操作按钮 */
.action-buttons {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  background: white;
  color: #374151;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s ease;
  text-align: left;
}

.action-btn:hover:not(:disabled) {
  border-color: #3b82f6;
  color: #3b82f6;
  background: rgba(59, 130, 246, 0.04);
  transform: translateY(-1px);
}

.action-btn.primary {
  background: linear-gradient(135deg, #3b82f6, #2563eb);
  color: white;
  border-color: transparent;
}

.action-btn.primary:hover:not(:disabled) {
  background: linear-gradient(135deg, #2563eb, #1d4ed8);
  color: white;
}

.action-btn.danger:hover:not(:disabled) {
  border-color: #ef4444;
  color: #ef4444;
  background: rgba(239, 68, 68, 0.04);
}

.action-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* 遮罩层 */
.sidebar-overlay {
  position: fixed;
  top: 70px;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.3);
  z-index: 40;
  backdrop-filter: blur(2px);
}

/* 加载状态 */
.loading-screen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
  backdrop-filter: blur(8px);
}

.loading-content {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.loading-spinner {
  width: 60px;
  height: 60px;
  position: relative;
}

.spinner-ring {
  width: 100%;
  height: 100%;
  border: 4px solid rgba(59, 130, 246, 0.1);
  border-top: 4px solid #3b82f6;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.loading-content h3 {
  font-size: 18px;
  font-weight: 600;
  color: #1f2937;
  margin: 0;
}

.loading-content p {
  font-size: 14px;
  color: #6b7280;
  margin: 0;
}

/* 消息提示 */
.toast {
  position: fixed;
  bottom: 24px;
  right: 24px;
  background: white;
  border-radius: 16px;
  padding: 16px 20px;
  display: flex;
  align-items: center;
  gap: 12px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
  transform: translateX(120%);
  transition: all 0.3s ease;
  z-index: 300;
  max-width: 400px;
  border: 1px solid rgba(0, 0, 0, 0.06);
}

.toast.show {
  transform: translateX(0);
}

.toast-error {
  border-left: 4px solid #ef4444;
}

.toast-success {
  border-left: 4px solid #10b981;
}

.toast button {
  background: none;
  border: none;
  color: #9ca3af;
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
  transition: all 0.2s ease;
}

.toast button:hover {
  background: rgba(0, 0, 0, 0.05);
  color: #6b7280;
}

/* 图标字体类 */
.icon-arrow-left::before {
  content: '←';
}
.icon-menu::before {
  content: '☰';
}
.icon-x::before {
  content: '×';
}
.icon-book::before {
  content: '📖';
}
.icon-location::before {
  content: '📍';
}
.icon-chevron-up::before {
  content: '▲';
}
.icon-chevron-down::before {
  content: '▼';
}
.icon-info::before {
  content: 'ℹ️';
}
.icon-message-circle::before {
  content: '💬';
}
.icon-more::before {
  content: '⋯';
}
.icon-send::before {
  content: '📤';
}
.icon-loader::before {
  content: '⟳';
}
.icon-alert-circle::before {
  content: '⚠️';
}
.icon-message::before {
  content: '💬';
}
.icon-user::before {
  content: '👤';
}
.icon-users::before {
  content: '👥';
}
.icon-star::before {
  content: '⭐';
}
.icon-zap::before {
  content: '⚡';
}
.icon-settings::before {
  content: '⚙️';
}
.icon-save::before {
  content: '💾';
}
.icon-history::before {
  content: '📋';
}
.icon-refresh::before {
  content: '🔄';
}
.icon-user-switch::before {
  content: '🔄';
}
.icon-log-out::before {
  content: '🚪';
}
.icon-check-circle::before {
  content: '✅';
}
.icon-message-square::before {
  content: '💬';
}

/* 响应式设计 */
@media (max-width: 768px) {
  .app-header {
    padding: 0 16px;
    height: 60px;
  }

  .theater-title {
    font-size: 16px;
  }

  .header-center {
    display: none;
  }

  .player-badge {
    padding: 6px 8px;
    gap: 8px;
  }

  .player-avatar-small {
    width: 28px;
    height: 28px;
  }

  .chat-main.sidebar-open {
    margin-right: 0;
  }

  .app-sidebar {
    width: 100%;
    top: 60px;
    height: calc(100vh - 60px);
  }

  .messages-wrapper {
    padding: 16px;
    gap: 16px;
  }

  .character-message {
    max-width: 85%;
  }

  .chat-input-area {
    padding: 12px 16px;
  }

  .input-wrapper {
    padding: 10px 14px;
  }

  .sidebar-content {
    padding: 16px;
    gap: 20px;
  }
}

@media (max-width: 480px) {
  .app-header {
    padding: 0 12px;
  }

  .header-left {
    gap: 12px;
  }

  .header-right {
    gap: 8px;
  }

  .player-info-mini {
    display: none;
  }

  .scene-banner-header {
    padding: 12px 16px;
  }

  .messages-wrapper {
    padding: 12px;
  }

  .avatar-img {
    width: 36px;
    height: 36px;
    border-radius: 10px;
  }

  .bubble-content {
    padding: 12px 14px;
    font-size: 14px;
  }

  .chat-input-area {
    padding: 10px 12px;
  }

  .bottom-toolbar {
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
  }

  .toolbar-actions {
    gap: 8px;
  }

  .toast {
    bottom: 16px;
    right: 16px;
    left: 16px;
    transform: translateY(120%);
  }

  .toast.show {
    transform: translateY(0);
  }
}
</style>
